package work.huangxin.share.handlerInterceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import work.huangxin.share.constant.RedisConstant;
import work.huangxin.share.domain.admin.UserAdminSys;
import work.huangxin.share.domain.other.Audience;
import work.huangxin.share.domain.other.WXSessionModel;
import work.huangxin.share.util.JWTUtil;
import work.huangxin.share.util.RedisUtil;
import work.huangxin.share.util.ThreadLocalUtil;
import work.huangxin.share.util.common.JsonUtils;
import work.huangxin.share.util.status.CodeEnum;
import work.huangxin.share.util.status.ResponseData;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Objects;

@Component
public class MyInterceptor implements HandlerInterceptor {


    @Resource
    private Audience audience;

    @Resource
    private RedisUtil redisUtil;



    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        //等到请求头信息authorization信息
        final String authHeader = request.getHeader("authorization");
        //后台管理系统鉴权
        if (request.getRequestURI().contains("/wx/admin/api")){
            UserAdminSys admin = (UserAdminSys) request.getSession().getAttribute("admin");
//            if (!Objects.isNull(admin)){
//                //如果session中已经有管理员信息
//                return true;
//            }
            try{
                if (null == audience){
                    WebApplicationContext factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
                    audience = (Audience) factory.getBean("audience");
                }
                Claims claims = JWTUtil.parseJWT(authHeader, audience.getBase64Secret());
                if (null == claims){
                    this.returnJson(response, JsonUtils.objectToJson(ResponseData.out(CodeEnum.SIGNATURE_NOT_ALLOW, "令牌出现错误")));
                }
                UserAdminSys adminSys = JsonUtils.jsonToPojo(claims.get("user").toString(), UserAdminSys.class);
                if (null == adminSys){
                    this.returnJson(response, JsonUtils.objectToJson(ResponseData.out(CodeEnum.SIGNATURE_NOT_ALLOW, "解析令牌出现错误")));
                }
                Long id = adminSys.getId();
                System.out.println(id);
                ThreadLocalUtil.set(id);
                //将管理员身份存入session中
                request.getSession().setAttribute("admin", adminSys);
                //TODO 放到redis
                redisUtil.set("admin:"+id,adminSys);
            }catch (Exception e){
                this.returnJson(response, JsonUtils.objectToJson(ResponseData.out(CodeEnum.SIGNATURE_NOT_ALLOW, "出现致命错误")));
                return false;
            }
            return true;
        }
        if ("OPTIONS".equals(request.getMethod())) {
            //测试服务器支持方法
            response.setStatus(HttpServletResponse.SC_OK);
            return false;
        } else {
            final String token = authHeader;//获取 token
            try {
                if (audience == null) {//获取配置信息
                    BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
                    audience = (Audience) factory.getBean("audience");
                }
                final Claims claims = JWTUtil.parseJWT(token, audience.getBase64Secret());//解密token,获取token内容
                //String userJson = (String) claims.get("user");
                //JSONObject jsonObject = JSON.parseObject(userJson);
                //Integer userId = (Integer) jsonObject.get("userId");
                //System.out.println(userId);
                //
                if (claims == null) {//解析失败,token有问题
                    this.returnJson(response, JsonUtils.objectToJson(ResponseData.out(CodeEnum.SIGNATURE_NOT_ALLOW, "令牌出现错误")));
                    return false;
                }
                //通过token解析出来的用户信息
                WXSessionModel user = JsonUtils.jsonToPojo(claims.get("user").toString(), WXSessionModel.class);//解析储存的user信息
                //将用户信息保存到session中
                //TODO:身份识别会出现问题
                request.getSession().setAttribute("user", user);



                ThreadLocalUtil.set(user.getUserId().longValue());
                //在redis中也保存一份user信息
                user.setToken(token);
                redisUtil.set(RedisConstant.userTokenInRedis +user.getUserId(),user,600);
            } catch (final Exception e) {
                this.returnJson(response, JsonUtils.objectToJson(ResponseData.out(CodeEnum.SIGNATURE_NOT_ALLOW, "出现致命错误")));
                return false;
            }
        }
        return true;
    }

    /**
     * 返回客户端数据
     */
    private void returnJson(HttpServletResponse response, String result) throws Exception {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        try {
            writer = response.getWriter();
            writer.print(result);

        } catch (IOException e) {
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

}
